package com.xwq.xwqaiagent.chatmemory;

import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.messages.Message;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 基于Redis的对话记忆实现
 * 使用Redis List结构存储对话记录，支持自动过期
 */
public class RedisBasedChatMemory implements ChatMemory {

    // Redis操作模板
    private final RedisTemplate<String, Message> redisTemplate;
    
    // 默认过期时间（7天）
    private final long DEFAULT_EXPIRE_HOURS = 168; 
    
    // 消息列表操作接口
    private final ListOperations<String, Message> listOps;

    /**
     * 构造方法：初始化Redis配置
     * @param redisTemplate 已配置好的RedisTemplate实例
     */
    public RedisBasedChatMemory(RedisTemplate<String, Message> redisTemplate) {
        this.redisTemplate = redisTemplate;
        this.listOps = redisTemplate.opsForList();
        
        // 配置Message的序列化器
        Jackson2JsonRedisSerializer<Message> serializer = new Jackson2JsonRedisSerializer<>(Message.class);
        redisTemplate.setValueSerializer(serializer);
    }

    /**
     * 添加消息到指定对话
     * @param conversationId 对话ID（作为Redis Key）
     * @param messages 要添加的消息列表
     */
    @Override
    public void add(String conversationId, List<Message> messages) {
        if (messages == null || messages.isEmpty()) return;

        // 批量右推消息到列表尾部
        listOps.rightPushAll(getKey(conversationId), messages);
        
        // 设置过期时间
        redisTemplate.expire(getKey(conversationId), DEFAULT_EXPIRE_HOURS, TimeUnit.HOURS);
    }

    /**
     * 获取最近N条对话记录
     * @param conversationId 对话ID
     * @param lastN 要获取的消息数量
     * @return 最近N条消息的不可变列表
     */
    @Override
    public List<Message> get(String conversationId, int lastN) {
        String key = getKey(conversationId);
        Long size = listOps.size(key);
        
        if (size == null || size == 0) {
            return Collections.emptyList();
        }

        // 计算获取范围（-lastN 到 -1）
        int start = Math.max(0, (int)(size - lastN));
        return listOps.range(key, start, -1);
    }

    /**
     * 清除指定对话记录
     * @param conversationId 要清除的对话ID
     */
    @Override
    public void clear(String conversationId) {
        redisTemplate.delete(getKey(conversationId));
    }

    /**
     * 生成Redis Key（添加命名空间）
     * @param conversationId 原始对话ID
     * @return 格式化后的Redis Key
     */
    private String getKey(String conversationId) {
        return "chat:memory:" + Objects.requireNonNull(conversationId);
    }

    // 可选：设置自定义过期时间
    public void setExpire(String conversationId, long duration, TimeUnit unit) {
        redisTemplate.expire(getKey(conversationId), duration, unit);
    }
}